package com.polaris.live.widget.gift

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.RelativeLayout
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.polaris.live.common.cacha.CacheUtil
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.databinding.WidgetGiftPagBinding
import com.polaris.live.manager.DownFileManager
import com.polaris.live.resp.bean.LiveShowPagBean
import com.polaris.live.resp.bean.MagicLampCountDownBean
import com.polaris.live.utils.file.FileUtils
import com.polaris.live.utils.file.FileUtils.getFilePath
import com.polaris.live.utils.image.ImageUtils
import com.polaris.live.widget.pag.PagWidgetView
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.libpag.PAGFile
import org.libpag.PAGImage
import java.io.File
import java.util.concurrent.ConcurrentLinkedQueue

/**
 * LiveMagicLampCountdownView 神灯倒计时控件
 *
 * @author Created by 天晴 on 2024/11/27/027 16:33
 */
class LiveMagicLampCountdownView(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs) {

    private val mBinding = WidgetGiftPagBinding.inflate(LayoutInflater.from(context), this, true)

    private val mLifecycleOwner: LifecycleOwner by lazy {
        context as? LifecycleOwner
            ?: throw IllegalArgumentException("View context must implement LifecycleOwner")
    }

    private val mWaitingList = ConcurrentLinkedQueue<MagicLampCountDownBean>()

    private var mGiftPag: PagWidgetView? = null

    private var mContentJob: Job? = null

    private var nowMagicLampCountDownBean: MagicLampCountDownBean? = null //当前在执行的神灯

    //是否展示礼物特效
    private var mIsOpenGiftAnimation = true

    private var back: ((data: MagicLampCountDownBean) -> Unit)? = null

    private val countdownPath = "static/lamp/countdown.pag" //倒计时
    private var mTimeJob: Job? = null

    init {
        downLoadPag()
        mLifecycleOwner.lifecycle.addObserver(object : LifecycleEventObserver {
            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    mPagJob?.cancel()
                    mPagJob = null
                    mContentJob?.cancel()
                    mContentJob = null
                    mTimeJob?.cancel()
                    mTimeJob = null
                }
            }
        })
        mBinding.skipLl.setOnSingleClickListener {
            mBinding.skipLl.visibility = View.GONE
            mBinding.llPag.removeAllViews()
            nowMagicLampCountDownBean?.let {
                val lotteryTime = it.lotteryTime
                val serverTime = CacheUtil.getServerTime()
                var time = lotteryTime - serverTime
                if (time < 0) {
                    complete(it)
                }
                if (time > ANIMATION_MAX_TIME) {
                    time = ANIMATION_MAX_TIME
                }
                executeAfterDelay(time) {
                    complete(it)
                }
            }
        }
    }

    fun openMagicLampCallBack(back: (data: MagicLampCountDownBean) -> Unit) {
        this.back = back
    }

    //添加神灯开奖时间
    fun addMagicLampPag(data: MagicLampCountDownBean) {
        if (mLifecycleOwner.lifecycle.currentState == Lifecycle.State.DESTROYED) {
            return
        }
        if (nowMagicLampCountDownBean == null) {
            nowMagicLampCountDownBean = data
            showPag(data)
        } else {
            mWaitingList.add(data)
        }
    }

    /**
     * 延时等待
     */
    private fun executeAfterDelay(time: Long, back: () -> Unit) {
        mTimeJob?.cancel()
        mTimeJob = null
        mTimeJob = CoroutineScopeManager.ioScope.launch {
            try {
                delay(time)
                withContext(CoroutineScopeManager.mainDispatcher) {
                    back.invoke()
                }
            } finally {
                if (coroutineContext[Job] == mTimeJob) {
                    mTimeJob = null
                }
            }

        }
    }

    //展示礼物
    private fun showPag(data: MagicLampCountDownBean) {
        val lotteryTime = data.lotteryTime
        val serverTime = CacheUtil.getServerTime()
        val time = lotteryTime - serverTime
        if (time < 0) { //领取时间超过当前时间直接领取
            complete(data)
            return
        }
        if (!mIsOpenGiftAnimation) { //关闭了动画,延时领取
            var cTime = lotteryTime - serverTime
            if (cTime > ANIMATION_MAX_TIME) { //大于10秒的 延时10秒领取
                cTime = ANIMATION_MAX_TIME
            }
            executeAfterDelay(cTime) {
                complete(data)
            }
            return
        }

        val path = getFilePath(FileUtils.getPagFile(), countdownPath)
        //如果文件里没有找到 就代表没有下载过 那么就去下载 然后播放下一个
        if (!File(path).exists()) {
            downLoadPag()
            return
        }


        mGiftPag = PagWidgetView(context)
        val layout =
            RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        layout.addRule(RelativeLayout.CENTER_HORIZONTAL)
        layout.addRule(RelativeLayout.CENTER_VERTICAL)
        mGiftPag?.layoutParams = layout
        mBinding.llPag.removeAllViews()
        mBinding.llPag.addView(mGiftPag)
        val pagFile = PAGFile.Load(path)
        mContentJob = CoroutineScopeManager.ioScope.launch {
            if (data.firstUserAvatar.isNotEmpty()) {
                val loadNetImageBitmap = ImageUtils.loadNetImageBitmap(context, data.firstUserAvatar)
                val pagImage = PAGImage.FromBitmap(loadNetImageBitmap)
                pagFile.replaceImage(0, pagImage)
            }
            withContext(CoroutineScopeManager.mainDispatcher) {
                mBinding.skipLl.visibility = View.VISIBLE
                mGiftPag?.apply {
                    setRepeatCount(1)
                    composition = pagFile

                    setOnPagEndCallback {
                        complete(data)
                    }
                    startPag()
                }
            }
        }


    }

    //展示下一个
    private fun showNext() {
        mGiftPag = null
        mWaitingList.poll()?.let {
            nowMagicLampCountDownBean = it
            showPag(it)
        }
    }

    private fun complete(data: MagicLampCountDownBean) {
        mBinding.skipLl.visibility = View.GONE
        back?.invoke(data)
        nowMagicLampCountDownBean = null
        showNext()
    }

    fun clearAllPag() {
        clearQueue()
        mBinding.llPag.removeAllViews()
    }

    fun clearQueue() {
        mWaitingList.clear()
        mLoadQueue.clear()
    }

    private var mIsDownloading = false   //是否正在下载中
    private val mLoadQueue = ConcurrentLinkedQueue<LiveShowPagBean>() //下载队列
    private var mPagJob: Job? = null


    //下载
    private fun downLoadPag() {
        val path = getFilePath(FileUtils.getPagFile(), countdownPath)
        //如果pag没有下载则下载pag去
        if (!File(path).exists()) {
            downPag(countdownPath) {
                nowMagicLampCountDownBean?.let {
                    showPag(it)
                }
            }
        }
    }

    private fun downPag(url: String, back: () -> Unit) {
        mPagJob?.cancel()
        mIsDownloading = true
        mPagJob = CoroutineScopeManager.ioScope.launch {
            try {
                val directory = FileUtils.getPagFile()
                val loadFileCallback = DownFileManager.loadFileCallback(directory, url)
                withContext(CoroutineScopeManager.mainDispatcher) {
                    mIsDownloading = false
                    loadFileCallback?.second?.let {
                        back.invoke()
                    }
                }
            } finally {
                if (coroutineContext[Job] == mPagJob) {
                    mPagJob = null
                }
            }
        }

    }

    //礼物动效开关
    fun setIsOpenGiftAnimation(isOpen: Boolean) {
        mIsOpenGiftAnimation = isOpen
        clearQueue()
    }

    companion object{
        const val ANIMATION_MAX_TIME = 10000L //动画时长
    }

}

